![]() ![]() |
Q
How I can translate a font name to a Postscript font file name? A The name of the Postscript font can be determined using information stored inside the FOND resource. This information is stored in the
Style-Mapping table, which is described on pages 4-99 through 4-105
in Inside Macintosh: Text.
Essentially, you'll take the FOND and style information, and build the complete Postscript name.
If you need the name of the Postscript font file, you can condense the Postscript name into the name of the file. The rule is to take the first 5 characters in the font name, and then add the first 3 characters that follow any dash. For example, the following Helvetica font: Helvetica-Bold-Oblique-Condensed Would become:
Once you've got the font file name, you can search for the corresponding file.
The file type is 'LWFN' and creator is '
One last thing -- the font can be stored in multiple suitcases, so if you get
to the last step above, you'll need to search all available Below are a couple of snippets of code -- one is a C translation of the Style
Mapping code found in
Inside Macintosh: Text, and the other is code I've used to walk the list of
#include <fonts.h> #include <Strings.h> typedef short int16; typedef long int32; typedef FamRec **FamRecHdl; typedef StyleTable *StyleTablePtr; #define MIN(a,b) ((a)<(b)?(a):(b)) void main (void); void GetPrinterFontName (Str255 screenName, Str255 printerName); int32 MyCompressStyle(Style aStyle); void MyNthStyleName(int32 index, Ptr q, Str255 s); void MyPSFontName(FamRec **fh, Style aStyle, Str255 PSName); void ConcatPStrings (Str255 targetStr, ConstStr255Param appendStr); void ConcatPStrings (Str255 targetStr, ConstStr255Param appendStr) { short appendLen; /* Figure out number of bytes to copy, up to 255 */ appendLen = MIN(appendStr[0], 255 - targetStr[0]); if (appendLen > 0) { BlockMoveData(appendStr+1, targetStr+targetStr[0]+1, (long) appendLen); targetStr[0] += appendLen; } } void main (void) { Str255 printer; // do standard mac init InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); InitCursor(); MaxApplZone(); MoreMasters(); MoreMasters(); MoreMasters(); GetPrinterFontName ("\pTimes", printer); Debugger(); } void GetPrinterFontName(Str255 screenName, Str255 printerName) { int16 fontNum; FMetricRec theMetrics; WidthTable **wTabHan; GetFNum( screenName, &fontNum); TextFont( fontNum ); TextFace (bold + italic); FontMetrics( &theMetrics ); wTabHan = (WidthTable **) theMetrics.wTabHandle; MyPSFontName((FamRecHdl) (**wTabHan).fHand, bold+italic, printerName); return; } int32 MyCompressStyle(Style aStyle) // A "Set of StyleItem" is mapped into [0..47], // assuming that condense and extend are mutually exclusive { int32 styleCode; styleCode = 0; if (bold & aStyle) styleCode = styleCode + 1; if (italic & aStyle) styleCode = styleCode + 2; if (outline & aStyle) styleCode = styleCode + 4; if (shadow & aStyle) styleCode = styleCode + 8; if (condense & aStyle) styleCode = styleCode + 16; else if (extend & aStyle) styleCode = styleCode + 32; return( styleCode ); } void MyNthStyleName(int32 index, Ptr q, Str255 s) { while (index > 1) { q = (Ptr) (q + *q + 1); // assumes q^ = stringlength < 128 ... index -= 1; } BlockMove(q, &s[0], *q + 1); // assumes q^ = stringlength < 127 ... return; } void MyPSFontName(FamRec **fh, Style aStyle, Str255 PSName) { StyleTablePtr stp; Ptr q; // pointer to Style-name table. Str255 styleName, suffixIndices; int32 i, nbOfStrings, offset, whichIndex; PSName[0] = '0'; offset = (**fh).ffStylOff; if (offset > 0) { q = ((Ptr) *fh) + offset; stp = (StyleTablePtr) q; q += sizeof (StyleTable); // style-name table follows style-mappingTable nbOfStrings = *(SInt16 *) q; // for range checking below q += sizeof (SInt16); // now pointing to basename of font BlockMove(q, (Ptr) PSName, *q + 1); // basename of font; assumes length < 128 whichIndex = stp->indexes[MyCompressStyle(aStyle)]; if (whichIndex > 1 && whichIndex <= nbOfStrings) { MyNthStyleName(whichIndex, q, suffixIndices); for (i=1;i <= suffixIndices[0];++i) { MyNthStyleName(suffixIndices[i], q, styleName); ConcatPStrings( PSName, styleName); } } } //ELSE corrupted FOND //else // no style mapping table in FOND //return( PSName ); } #define _SanityCheck_ 1 #ifndef _SanityCheck_ #define _SanityCheck_ 1 #endif // Note that these don't set any error variables -- in general, any routines that report // an OSErr should have a variable inside the routine that gets set appropriately -- and // reports a "default" error code when it isn't already set to noErr. #if _SanityCheck_ #define FAIL_NIL(y,msg) {if (y == NULL) {DebugStr(msg); goto error;}} #define FAIL_OSERR(y,msg) {if (y != noErr) {DebugStr(msg); goto error;}} #define FAIL_FALSE(y,msg) {if (!y) {DebugStr(msg); goto error;}} #define SIGNAL_ERROR(msg) {DebugStr(msg); goto error;} #else #define FAIL_NIL(y,msg) {if (y == NULL) {goto error;}} #define FAIL_OSERR(y,msg) {if (y != noErr) { goto error;}} #define FAIL_FALSE(y,msg) {if (!y) {goto error;}} #define SIGNAL_ERROR(msg) {goto error;} #endif void main (void); // This routine returns the first available installed file that // includes the font passed in. // It also returns a magic cookie that can be used to // retrieve any other files that // contain that font. OSErr FontNameToFSSpec (ConstStr31Param inFont, FSSpec *outFile, long *outCookie); OSErr NextFontToFSSpec (long *inOutCookie, FSSpec *outFile); // We borrow these routines from MoreFiles, since they are so handy. /*****************************************************************************/ pascal OSErr GetFileLocation(short refNum, short *vRefNum, long *dirID, StringPtr fileName); /* Get the location of an open file. The GetFileLocation function gets the location (volume reference number, directory ID, and fileName) of an open file. refNum input: The file reference number of an open file. vRefNum output: The volume reference number. dirID output: The parent directory ID. fileName input: Points to a buffer (minimum Str63) where the filename is to be returned or must be nil. output: The filename. Result Codes noErr 0 No error nsvErr -35 Specified volume doesn't exist fnOpnErr -38 File not open rfNumErr -51 Reference number specifies nonexistent access path __________ See also: FSpGetFileLocation */ /*****************************************************************************/ pascal OSErr FSpGetFileLocation(short refNum, FSSpec *spec); /* Get the location of an open file in an FSSpec record. The FSpGetFileLocation function gets the location of an open file in an FSSpec record. refNum input: The file reference number of an open file. spec output: FSSpec record containing the file name and location. Result Codes noErr 0 No error nsvErr -35 Specified volume doesn't exist fnOpnErr -38 File not open rfNumErr -51 Reference number specifies nonexistent access path __________ See also: GetFileLocation */ /*****************************************************************************/ pascal OSErr GetFileLocation(short refNum, short *vRefNum, long *dirID, StringPtr fileName) { FCBPBRec pb; OSErr error; pb.ioNamePtr = fileName; pb.ioVRefNum = 0; pb.ioRefNum = refNum; pb.ioFCBIndx = 0; error = PBGetFCBInfoSync(&pb); *vRefNum = pb.ioFCBVRefNum; *dirID = pb.ioFCBParID; return ( error ); } /*****************************************************************************/ pascal OSErr FSpGetFileLocation(short refNum, FSSpec *spec) { return ( GetFileLocation(refNum, &(spec->vRefNum), &(spec->parID), spec->name) ); } OSErr FontNameToFSSpec (ConstStr31Param inFont, FSSpec *outFile, long *outCookie) { OSErr theErr= noErr; short homeFile; Handle fond; *outCookie = NULL; fond = GetNamedResource('FOND', inFont); theErr = ResError(); FAIL_OSERR (theErr, "\p Failed to find any installed font file with that font name") FAIL_NIL (fond, "\p Failed to find any installed font file with that font name") homeFile = HomeResFile (fond); theErr = ResError(); FAIL_OSERR (theErr, "\p Failed to find the resource's home") theErr = FSpGetFileLocation(homeFile, outFile); FAIL_OSERR (theErr, "\p couldn't convert the reference to a file spec") // We succeeded. Set our cookie and return. *outCookie = (long) fond; return noErr; error: if (theErr != noErr) theErr = paramErr; *outCookie = NULL; return theErr; } OSErr NextFontToFSSpec (long *inOutCookie, FSSpec *outFile) { OSErr theErr= noErr; short homeFile; Handle fond = (Handle) *inOutCookie; if (fond == NULL) return paramErr; fond = GetNextFOND (fond); theErr = ResError(); FAIL_OSERR (theErr, "\p No more fonds left with that name") FAIL_NIL (fond, "\p No more fonds left with that name") homeFile = HomeResFile (fond); theErr = ResError(); FAIL_OSERR (theErr, "\p Failed to find the resource's home") theErr = FSpGetFileLocation(homeFile, outFile); FAIL_OSERR (theErr, "\p couldn't convert the reference to a file spec") // We succeeded. Set our cookie and return. *inOutCookie = (long) fond; return noErr; error: if (theErr != noErr) theErr = paramErr; *inOutCookie = NULL; return theErr; } void main (void) { long oreo; FSSpec fontFile; OSErr theErr; // We just drop into the debugger here to report the returned FSSpecs. theErr = FontNameToFSSpec("\pPalatino", &fontFile, &oreo); Debugger(); while (oreo != 0) { theErr = NextFontToFSSpec (&oreo, &fontFile); Debugger(); } } [Nov 17 1997] |
Developer Documentation | Technical Notes | Development Kits | Sample Code |